<template>
  <el-drawer
    size="43%"
    style="border-radius: 24px"
    :close-on-click-modal="false"
    :with-header="true"
    :show-close="false"
  >
    <template #header>
      <span class="unselectable">添加Spu</span>
      <el-icon
        style="color: #000; font-size: 25px; filter: drop-shadow(0 0 3px #000)"
        @click="cancel($parent)"
      >
        <Close />
      </el-icon>
    </template>
    <template #default>
      <el-form>
        <el-form-item label="SPU名称">
          <el-input v-model="SpuParams.spuName"></el-input>
        </el-form-item>
        <el-form-item label="SPU品牌">
          <el-select v-model="SpuParams.tmId" placeholder="请下拉选择数据">
            <el-option
              v-for="item in grandData"
              :key="item.id"
              :label="item.tmName"
              :value="item.id"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="SPU描述">
          <el-input type="textarea" v-model="SpuParams.description"></el-input>
        </el-form-item>
        <el-form-item label="SPU图片">
          <el-upload
            v-model:file-list="SpuParams.spuImageList"
            action="/api/admin/product/fileUpload"
            list-type="picture-card"
            :on-preview="handlePictureCardPreview"
          >
            <el-icon>
              <Plus />
            </el-icon>
          </el-upload>

          <el-dialog v-model="dialogVisible">
            <img
              w-full
              :src="dialogImageUrl"
              alt="Preview Image"
              style="height: 100%; width: 100%"
            />
          </el-dialog>
        </el-form-item>
        <el-form-item label="SPU销售属性">
          <el-select
            v-model="selectedAttr"
            :placeholder="`还有 ${unSelectAttrLength}个属性未选择`"
            style="width: 180px"
            @change="changeSelectedValue"
          >
            <el-option
              v-for="item in missingData"
              :key="item.baseSaleAttrId"
              :label="item.saleAttrName"
              :value="item.saleAttrName"
            />
          </el-select>
          <el-button
            type="primary"
            icon="Plus"
            style="margin-left: 10px"
            @click="addSaleAttr"
            :disabled="disabled"
          >
            添加销售属性
          </el-button>
        </el-form-item>
        <el-form-item>
          <el-table border :data="SpuParams.spuSaleAttrList">
            <el-table-column
              align="center"
              label="序号"
              width="70px"
              prop="baseSaleAttrId"
            ></el-table-column>
            <el-table-column
              align="center"
              label="属性名"
              prop="saleAttrName"
              width="70px"
            ></el-table-column>
            <el-table-column align="center" label="属性值">
              <template #default="{ row, $index }">
                <el-tag
                  v-for="item in row.spuSaleAttrValueList"
                  :key="item.id"
                  closable
                  style="margin-right: 8px"
                  @close="removeAttrValue(row, item)"
                >
                  {{ item.saleAttrValueName }}
                </el-tag>
                <el-button
                  size="small"
                  icon="Plus"
                  type="primary"
                  @click="addAttrValue(row, $index, true)"
                  v-show="!editingRows[$index]"
                ></el-button>
                <el-input
                  v-show="editingRows[$index]"
                  style="width: 70px; height: 23px"
                  @blur="blurValue(row, $index, false)"
                  placeholder="属性值"
                  v-model="attrValue"
                ></el-input>
              </template>
            </el-table-column>
            <el-table-column align="center" label="操作" width="70px">
              <template #default="{ row, $index }">
                <el-button
                  icon="Delete"
                  type="danger"
                  size="small"
                  @click="deleteAttr($index)"
                ></el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-form-item>
      </el-form>
    </template>
    <template #footer>
      <el-button @click="cancel($parent)">取消</el-button>
      <el-button
        type="primary"
        style="margin-right: 14px"
        @click="saveData($parent)"
      >
        保存
      </el-button>
    </template>
  </el-drawer>
</template>

<script lang="ts">
export default {
  name: 'cardSpu',
}
</script>

<script setup lang="ts">
import { ref, computed, watch, nextTick } from 'vue'
import {
  reqGetGrand,
  reqGetImage,
  reqGetAttr,
  reqGetSall,
  reqSaveOrUpdate,
} from '../../../../api/product/spu'
import {
  AttributeArray,
  grandArray,
  ImageDataArray,
  ImageData,
  SPU,
  SpuSaleAttrsArray,
} from '../../../../api/product/spu/type'
import { ElMessage } from 'element-plus'
import categorizeStore from '../../../../store/modules/categorize'
const useCategorizeStore = categorizeStore()
//存储【颜色，版本，尺寸】
let fixedAttrValue = ref<AttributeArray>([])
//属性值
let attrValue = ref('')
// 使用一个数组来跟踪每行的编辑状态
const editingRows = ref([])
//控制变量
let disabled = ref(true)
// 找出缺失的项
const missingData = ref([
  {
    baseSaleAttrId: 1,
    saleAttrName: '',
    spuSaleAttrValueList: [],
  },
])
//用于存储预览时候的图片url
let dialogImageUrl = ref<string>('')
//预览对话框控制
let dialogVisible = ref<boolean>(false)
//收集已选中的下拉的属性
let selectedAttr = ref('')
// 为 SpuParams 提供一个初始的 SPU 对象,用于接收父组件的row
let SpuParams = ref<SPU>({
  id: 0, // 或者其他合适的默认值
  createTime: '',
  updateTime: '',
  spuName: '',
  description: '',
  category3Id: 0,
  tmId: 0,
  spuImageList: [] as ImageDataArray,
  spuPosterList: null,
  spuSaleAttrList: [] as SpuSaleAttrsArray,
})
//获取已经选中的select对象
let selectedValueObject = ref({})
//定义还未选择的销售属性的数量
let unSelectAttrLength = ref(3)
//存储品牌
let grandData = ref<grandArray>([])
//取消回调
function cancel(parent: any) {
  //关闭抽屉
  parent.drawer = false
}

// 定义一个函数来找出缺失的name属性值和id
function findMissing(arr1: any, arr2: any) {
  // 创建一个对象，用于快速查找数组2中的arrName属性
  const arr2Map = ref({})
  arr2.forEach((item: any) => {
    arr2Map.value[item.saleAttrName] = item.baseSaleAttrId //
  })

  // 找出缺失的项
  const missingItems = ref([])
  arr1.forEach((item1: any) => {
    if (!(item1.name in arr2Map.value)) {
      // 这里仍然使用 item1.name，因为我们要检查 arr1 中的 name
      missingItems.value.push({
        saleAttrName: item1.name,
        baseSaleAttrId: item1.id,
      })
    }
  })
  // 打印缺失的项
  return missingItems.value
}

//计算还未选择的销售属性的个数
function computeAmout() {
  //计算未选择的销售属性的个数
  let unSelectAttrAmount = computed(() => {
    // 使用可选链 (?.) 操作符来安全地访问嵌套属性
    const saleAttrListLength =
      fixedAttrValue.value?.length ??
      0 /* 空值合并操作符 (??)  --我们使用 ?? 来提供一个默认值（在这种情况下是 0）当左侧的表达式结果为 null 或 undefined 时。这确保了即使 fixedAttrValue 是 null 或未定义，saleAttrListLength 也会是一个数字，从而避免在计算未选择属性个数时出现错误。 */
    const posterListLength = SpuParams.value.spuSaleAttrList?.length ?? 0
    // 计算未选择的销售属性个数
    // 注意：如果 fixedAttrValue 为 null 或未定义，我们将其长度视为 0
    return saleAttrListLength - posterListLength
  })
  //赋值
  unSelectAttrLength.value = unSelectAttrAmount.value
}
//获取父组件的spu数据（不完整）（row）
async function getFatherSpu(row: any) {
  //id
  SpuParams.value.id = row.id
  SpuParams.value.category3Id = row.category3Id
  //清空
  selectedAttr.value = ''
  //数据回赋，品牌的id
  SpuParams.value.tmId = row.tmId
  //描述回调赋值,用于显示到页面上面
  SpuParams.value.description = row.description
  //名称回调赋值,用于显示到页面上面
  SpuParams.value.spuName = row.spuName
  //发送请求,获取品牌
  const grandResult = await reqGetGrand()
  //如果获取成功
  if (grandResult.code == 200) {
    //把品牌赋值给回调数据
    grandData.value = grandResult.data as grandArray
  }
  //发送请求 ,获取照片墙,需要携带id，这个id就是从父组件获取的对应的id
  const picResult = await reqGetImage(row.id)
  //如果获取成功
  if (picResult.code == 200) {
    //赋值
    SpuParams.value.spuImageList = picResult.data.map((item: ImageData) => {
      return {
        name: item.imgName,
        url: item.imgUrl,
      }
    })
  }
  //获取【版本】，【颜色】，【尺码】
  const threeAttr = await reqGetSall()
  //如果获取成功
  if (threeAttr.code == 200) {
    //回调赋值用于显示到页面
    fixedAttrValue.value = threeAttr.data
  }
  //获取该商品已有的属性接口
  const selectedAttrResult = await reqGetAttr(row.id)
  //把已有的销售属性和属性值回调赋值
  SpuParams.value.spuSaleAttrList = selectedAttrResult.data
  //调用计算函数
  computeAmout()
  //计算还未选择的销售属性和id
  missingData.value = findMissing(
    fixedAttrValue.value,
    SpuParams.value.spuSaleAttrList,
  )
}

//预览钩子
function handlePictureCardPreview(file: any) {
  //赋值，用于显示对话框
  dialogImageUrl.value = file.url
  //打开dialog
  dialogVisible.value = true
}
//删除属性table行
function deleteAttr($index: number) {
  SpuParams.value.spuSaleAttrList?.splice($index, 1)
  //重新计算未选择的销售属性
  missingData.value = findMissing(
    fixedAttrValue.value,
    SpuParams.value.spuSaleAttrList,
  )
  //重新计算个数
  computeAmout()
}
//添加销售属性回调
function addSaleAttr() {
  //增加销售属性
  SpuParams.value.spuSaleAttrList?.push(selectedValueObject.value)
  //重新计算
  //重新计算未选择的销售属性
  missingData.value = findMissing(
    fixedAttrValue.value,
    SpuParams.value.spuSaleAttrList,
  )
  //重新计算个数
  computeAmout()
  //清空下拉菜单选中项
  selectedAttr.value = ''
}
//监听table数据的变化
watch(
  () => SpuParams.value.spuSaleAttrList?.length,
  () => {
    if (SpuParams.value.spuSaleAttrList?.length >= 3) {
      disabled.value = true
    }
  },
)
//监听select选中的数据的变换
watch(
  () => selectedAttr.value,
  () => {
    if (selectedAttr.value) {
      disabled.value = false
    } else {
      disabled.value = true
    }
  },
)
//当下拉菜单选中的值发生变化的时候
function changeSelectedValue() {
  selectedValueObject.value = missingData.value.find(
    (item) => item.saleAttrName === selectedAttr.value,
  )
  selectedValueObject.value.spuSaleAttrValueList = []
}
// 切换编辑状态的方法
function addAttrValue(row, index, isEditing) {
  editingRows.value[index] = isEditing
}
//输入框失去焦点
function blurValue(row, index, isEditing) {
  editingRows.value[index] = isEditing
  //如果输入框有值，允许push
  if (attrValue.value) {
    //push
    row.spuSaleAttrValueList.push({
      baseSaleAttrId: row.baseSaleAttrId,
      saleAttrName: row.saleAttrName,
      saleAttrValueName: attrValue.value,
    })
    //清空输入框值
    attrValue.value = ''
  }
}
//移除属性值
function removeAttrValue(row, item) {
  row.spuSaleAttrValueList.splice(row.spuSaleAttrValueList.indexOf(item), 1)
}
//保存
async function saveData(parent) {
  //处理url路径
  SpuParams.value.spuImageList = SpuParams.value.spuImageList?.map((item) => {
    return {
      imgName: item.name,
      imgUrl: (item.response && item.response.data) || item.url,
    }
  })

  const result = await reqSaveOrUpdate(SpuParams.value)

  if (!SpuParams.value.id) {
    parent.currentPage = 1
    parent.getSpu()
  }
  if (SpuParams.value.id) {
    parent.getSpu()
  }
  setTimeout(() => {
    //抽屉关闭
    parent.drawer = false
    ElMessage.success('保存成功')
  }, 200)
}
//初始化spu
async function initSpu() {
  /*  Object.assign(SpuParams.value, {
    category3Id: useCategorizeStore.infoId3,
    description: '',
    spuImageList: [] as ImageDataArray,
    spuName: '',
    spuSaleAttrList: [] as SpuSaleAttrsArray,
    tmId: '',
  }) */
  Object.assign(SpuParams.value, {
    id: 0,
    category3Id: useCategorizeStore.infoId3, //收集三级分类的ID
    spuName: '', //SPU的名字
    description: '', //SPU的描述
    tmId: '', //品牌的ID
    spuImageList: [] as ImageDataArray,
    spuSaleAttrList: [] as SpuSaleAttrsArray,
  })
  //获取【版本】，【颜色】，【尺码】
  const threeAttr = await reqGetSall()
  //如果获取成功
  if (threeAttr.code == 200) {
    //回调赋值用于显示到页面
    fixedAttrValue.value = threeAttr.data
  }
  //发送请求,获取品牌
  const grandResult = await reqGetGrand()
  //如果获取成功
  if (grandResult.code == 200) {
    //把品牌赋值给回调数据
    grandData.value = grandResult.data as grandArray
  }
  unSelectAttrLength.value = 3
  //重新计算未选择的销售属性
  missingData.value = findMissing(
    fixedAttrValue.value,
    SpuParams.value.spuSaleAttrList,
  )
}
//对外暴露
defineExpose({ getFatherSpu, initSpu })
</script>

<style>
.avatar-uploader .el-upload {
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
}

.avatar-uploader .el-upload:hover {
  border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  text-align: center;
}
</style>
